#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <Includes.h>
#include <EC600S_AT/AT.h>
#include <EC600S_AT/AT_EC600S.h>
#include <DRV_Neul.h>
#include <DRV_EC600S.h>
#include <OPP_Debug.h>
//#include <SVS_Time.h>
#include <SVS_Para.h>

extern neul_dev_info_t ec600s_dev;


int AtResponseQURCCFG(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char port[10];

    DEBUG_LOG(DEBUG_MODULE_EC600S, DLL_INFO, "AtResponseQURCCFG==>%s\r\n",buffer);
    if(NULL == strstr(buffer,"OK"))
        return 1;
	ret=sscanf(buffer,"\r\n%*[^:]:%*[^,],%s%*[\r\n]",port);
    if(1!=ret)
    {
        return 2;
    }
    //urcport
    if(0!=strcmp(port,URCPORT_DEF))
    {
        return 3;
    }

    return 0;
}

int AtResponseCGREG(char *buffer, int len, unsigned char *exdata)
{
    int cfg,reg;
    int ret;

    DEBUG_LOG(DEBUG_MODULE_EC600S, DLL_INFO, "AtResponseCGREG==>%s\r\n",buffer);
    if(NULL == strstr(buffer,"OK"))
        return 1;

	ret=sscanf(buffer,"\r\n%*[^:]:%d,%d%*[\r\n]",&cfg,&reg);
    if(2!=ret)
    {
        return 2;
    }
    DEBUG_LOG(DEBUG_MODULE_EC600S, DLL_INFO, "AtResponseCGREG==>cfg,reg\r\n",cfg,reg);

    if(reg==1||reg==5)
        Ec600sStSet(EC600S_DEV_READY);
    if(reg < INVALID_REG)
        Ec600sRegStSet((EN_REG_STATE)reg);

    //主动上报结果
    if(cfg!=CGREG_URC)
    {
        return 3;
    }

    return 0;
}

int AtResponseIPR(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    int rate;

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret=sscanf(buffer,"\r\n%*[^:]:%d%*[\r\n]",&rate);
    if(1!=ret)
    {
        return 2;
    }
    if(rate!=BAUD_DEF)
    {
        return 3;
    }
    return 0;
}

int AtResponseCGSN(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char imei_tmp[NEUL_IMEI_LEN]={0};
    unsigned int length=NEUL_IMEI_LEN;

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
    ret=sscanf(buffer,"\r\n%s%*[\r\n]",ec600s_dev.imei);
    if(1!=ret)
    {
        return 2;
    }
    if(exdata!=NULL)
        strcpy((char *)exdata,(char *)ec600s_dev.imei);
    //noted by wangtao
    ret=AppParaRead(APS_PARA_MODULE_APS_EC600S, EC600S_IMEI_ID, (unsigned char *)imei_tmp, &length);
    if(ret!=0 || (ret==0&&strcmp((char *)ec600s_dev.imei,imei_tmp)!=0))
    {
        ret=AppParaWrite(APS_PARA_MODULE_APS_EC600S, EC600S_IMEI_ID, (unsigned char *)ec600s_dev.imei, NEUL_IMEI_LEN);
        if(ret!=0)
        {
            ret=AppParaWrite(APS_PARA_MODULE_APS_EC600S, EC600S_IMEI_ID, (unsigned char *)ec600s_dev.imei, NEUL_IMEI_LEN);
        }
    }

    return 0;
}

int AtResponseCIMI(char *buffer, int len, unsigned char *exdata)
{
    int ret;

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret=sscanf(buffer,"\r\n%s%*[\r\n]",ec600s_dev.imsi);
    if(1!=ret)
    {
        return 2;
    }
    if(exdata!=NULL)
        strcpy((char *)exdata,(char *)ec600s_dev.imsi);
    return 0;

}

int AtResponseQCCID(char *buffer, int len, unsigned char *exdata)
{
    int ret;

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
    ret=sscanf(buffer,"\r\n%*[^:]:%s%*[\r\n]",ec600s_dev.nccid);
    if(1!=ret)
    {
        return 2;
    }
    if(exdata!=NULL)
        strcpy((char *)exdata,(char *)ec600s_dev.nccid);

    return 0;
}

int AtResponseATI(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char pid[NEUL_MANUFACT_LEN]={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
    ret=sscanf(buffer,"\r\n%*[^:]:%s%*[\r\n]",pid);
    if(1!=ret)
    {
        return 2;
    }
    if(exdata!=NULL)
        strcpy((char *)exdata,pid);

    return 0;
}

int AtResponseGMR(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char ver[NEUL_VER_LEN]={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret = sscanf(buffer, "%*[\r\n]%[^\r\n]",ver);
    if(1!=ret)
    {
        return 2;
    }
    if(exdata!=NULL)
        strcpy((char *)exdata,ver);

    return 0;
}

int AtResponseQENG(char *buffer, int len, unsigned char *exdata)
{
    int ret;
	ST_QENG q={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }

    sscanf(buffer,"%*[^,],\"%[^\"]\"%*[^\r\n]",q.state);

    if(strstr(buffer,"GSM"))
    {
        ret=sscanf(buffer,"%*[^,],\"%[^\"]\",\"%[^\"]\",%d,%d,%d,%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%*[^\r\n]",q.state,q.mode,
            &q.gsm.mcc,&q.gsm.mnc,&q.gsm.lac,&q.gsm.cellid,&q.gsm.bsic,&q.gsm.arfcn,&q.gsm.band,&q.gsm.rxlev,&q.gsm.rla,&q.gsm.txp,&q.gsm.drx,&q.gsm.c1,&q.gsm.c2,&q.gsm.gprs);
        if(ret!=16)
            return 1;
        //printf("%s,%s,%d,%d,%d,%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",q.state,q.mode,
        //    q.gsm.mcc,q.gsm.mnc,q.gsm.lac,q.gsm.cellid,q.gsm.bsic,q.gsm.arfcn,q.gsm.band,q.gsm.rxlev,q.gsm.rla,q.gsm.txp,q.gsm.drx,q.gsm.c1,q.gsm.c2,q.gsm.gprs);

    }
    else if(strstr(buffer,"WCDMA"))
    {
         ret=sscanf(buffer,"%*[^,],\"%[^\"]\",\"%[^\"]\",%d,%d,%d,%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%*[^\r\n]",q.state,q.mode,
            &q.wcdma.mcc,&q.wcdma.mnc,&q.wcdma.lac,&q.wcdma.cellid,&q.wcdma.uarfcn,&q.wcdma.psc,&q.wcdma.rac,&q.wcdma.rscp,&q.wcdma.ecio,&q.wcdma.phych,&q.wcdma.sf,&q.wcdma.slot,&q.wcdma.speech_code,&q.wcdma.comMod);
        if(ret!=16)
            return 1;

        //printf("%s,%s,%d,%d,%d,%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",q.state,q.mode,
        //    q.wcdma.mcc,q.wcdma.mnc,q.wcdma.lac,q.wcdma.cellid,q.wcdma.uarfcn,q.wcdma.psc,q.wcdma.rac,q.wcdma.rscp,q.wcdma.ecio,q.wcdma.phych,q.wcdma.sf,q.wcdma.slot,q.wcdma.speech_code,q.wcdma.comMod);
    }
    else if(strstr(buffer,"LTE"))
    {
        ret=sscanf(buffer,"%*[^,],\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",%d,%d,%x,%d,%d,%d,%d,%d,%x,%d,%d,%d,%d,%d%*[^\r\n]",q.state,q.mode,q.lte.is_tdd,
            &q.lte.mcc,&q.lte.mnc,&q.lte.cellid,&q.lte.pcid,&q.lte.earfcn,&q.lte.freq_band_ind,&q.lte.ul_bandwidth,&q.lte.dl_bandwidth,&q.lte.tac,&q.lte.rsrp,&q.lte.rsrq,&q.lte.rssi,&q.lte.sinr,&q.lte.srxlev);
        if(ret!=17)
            return 1;

        //printf("%s,%s,%s,%d,%d,%x,%d,%d,%d,%d,%d,%x,%d,%d,%d,%d,%d\r\n",q.state,q.mode,q.lte.is_tdd,
        //    q.lte.mcc,q.lte.mnc,q.lte.cellid,q.lte.pcid,q.lte.earfcn,q.lte.freq_band_ind,q.lte.ul_bandwidth,q.lte.dl_bandwidth,q.lte.tac,q.lte.rsrp,q.lte.rsrq,q.lte.rssi,q.lte.sinr,q.lte.srxlev);
    }

    memcpy(exdata,&q,sizeof(ST_QENG));
    return 0;
}

int AtResponseCOPS(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    ST_COPS c={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
    //TA returns the current mode and the currently selected operator.
    //If no operator is selected, <format>, <oper> and <Act> are omitted
    if(strchr(buffer,','))
    {
        ret=sscanf(buffer,"%*[^:]:%d,%d,\"%[^\"]\",%d%*[\r\n]",&c.mode,&c.format,c.oper,&c.act);
        if(ret!=4)
            return 2;
    }
    else
    {
        ret=sscanf(buffer,"%*[^:]:%d%*[\r\n]",&c.mode);
        if(ret!=1)
            return 2;
    }
    memcpy(exdata,&c,sizeof(ST_COPS));
    return 0;
}

int AtResponseCSQ(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    ST_CSQ c={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
    ret=sscanf(buffer,"%*[^:]:%d,%d%*[\r\n]",&c.rssi,&c.ber);
    if(ret!=2)
        return 2;
    memcpy(exdata,&c,sizeof(ST_CSQ));
    return 0;
}

int AtResponseCCLK(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    ST_TIME t={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	if(strrchr(buffer,'+'))
	{
		ret = sscanf(buffer, "%*[^:]: \"%hu/%hhu/%hhu,%hhu:%hhu:%hhu+%hhu\"%*[^\r\n]",
			&t.Year, &t.Month, &t.Day, &t.Hour, &t.Min, &t.Sencond, &t.Zone);
    }
	else
    {
		ret = sscanf(buffer, "%*[^:]: \"%hu/%hhu/%hhu,%hhu:%hhu:%hhu-%hhu\"%*[^\r\n]",
			&t.Year, &t.Month, &t.Day, &t.Hour, &t.Min, &t.Sencond, &t.Zone);
		t.Zone = 0-t.Zone;
	}

    if(ret!=7)
        return 2;
    memcpy(exdata,&t,sizeof(ST_TIME));
    return 0;
}

int AtResponseCGPADDR(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char ip[NEUL_IP_LEN];

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret = sscanf(buffer, "%*[^\"]\"%[^\"]\"%*[^\r\n]",ip);
    if(ret!=1)
        return 2;
    memcpy(exdata,ip,NEUL_IP_LEN);
    return 0;
}

int AtResponseCGMR(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char ver[NEUL_VER_LEN]={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret = sscanf(buffer, "%*[\r\n]%[^\r\n]",ver);
    if(ret!=1)
        return 2;
    if(exdata)
        memcpy(exdata,ver,NEUL_VER_LEN);
    return 0;

}

int AtResponseCGCONTRDP(char *buffer, int len, unsigned char *exdata)
{
    int ret;
    char apn[APN_NAME_LEN]={0};

    if(NULL == strstr(buffer,"OK"))
    {
        return 1;
    }
	ret = sscanf(buffer, "%*[^,],%*[^,],\"%[^\"]\"%*[^\r\n]",apn);
    if(ret!=1)
        return 2;

    memcpy(exdata,apn,APN_NAME_LEN);
    return 0;

}

ST_CMD initCmd[]={
    {"ATE0","ATE0\r",300,AtResponseComm,NULL,NULL},
    {"AT_QURCCFG?","AT+QURCCFG=\"urcport\"\r",300,AtResponseQURCCFG,"AT_CGREG?",NULL},
    {"AT_QURCCFG","AT+QURCCFG=\"urcport\",\"uart1\"\r",300,AtResponseComm,NULL,NULL},
    {"AT_CGSN","AT+CGSN\r",300,AtResponseCGSN,NULL,NULL},
    {"AT_CGREG?","AT+CGREG?\r",300,AtResponseCGREG,"AT_IPR?",NULL},
    {"AT_CGREG=1","AT+CGREG=1\r",300,AtResponseComm,NULL,NULL},
    {"AT_IPR?","AT+IPR?\r",300,AtResponseIPR,"AT&W",NULL},
    {"AT_IPR","AT+IPR=115200\r",300,AtResponseComm,NULL,NULL},
    {"AT_CTZR","AT+CTZR=1\r",300,AtResponseComm,NULL,NULL},
    {"AT&W","AT&W\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD shutdownCmd[]={
    {"AT_QPOWD","AT+QPOWD\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD imeiCmd[]={
    {"AT_CGSN","AT+CGSN\r",300,AtResponseCGSN,NULL,NULL},
};

ST_CMD imsiCmd[]={
    {"AT_CIMI","AT+CIMI\r",300,AtResponseCIMI,NULL,NULL},
};

ST_CMD qccidCmd[]={
    {"AT_QCCID","AT+QCCID\r",300,AtResponseQCCID,NULL,NULL},
};

ST_CMD atiCmd[]={
    {"ATI","ATI\r",300,AtResponseATI,NULL,NULL},
};

ST_CMD gmrCmd[]={
    {"AT_GMR","AT+GMR\r",300,AtResponseGMR,NULL,NULL},
};

ST_CMD qengCmd[]={
    {"AT_QENG","AT+QENG=\"servingcell\"\r",300,AtResponseQENG,NULL,NULL},
};

ST_CMD qcfgCmd[]={
    {"AT_QCFG","AT+QCFG=\"%s\",%d\r",1000,NULL,NULL,NULL},
};

ST_CMD copsCmd[]={
    {"AT_COPS","AT+COPS?\r",300,AtResponseCOPS,NULL,NULL},
};

ST_CMD csqCmd[]={
    {"AT_CSQ","AT+CSQ\r",300,AtResponseCSQ,NULL,NULL},
};

ST_CMD cclkCmd[]={
    {"AT_CCLK","AT+CCLK?\r",300,AtResponseCCLK,NULL,NULL},
};

ST_CMD cgpaddrCmd[]={
    {"AT_CGPADDR","AT+CGPADDR\r",300,AtResponseCGPADDR,NULL,NULL},
};

ST_CMD cgmrCmd[]={
    {"AT_CGMR","AT+CGMR\r",300,AtResponseCGMR,NULL,NULL},
};

ST_CMD cgcontrdpCmd[]={
    {"AT_CGCONTRDP","AT+CGCONTRDP\r",300,AtResponseCGCONTRDP,NULL,NULL},
};


int Ec600sAT_FuncInit()
{
    return Ec600sAtCmd(initCmd,ITEMS_OF(initCmd));
}

int Ec600sAT_QPOWD()
{
    return Ec600sAtCmd(shutdownCmd, ITEMS_OF(shutdownCmd));
}

int Ec600sAT_CGSN(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&imeiCmd[0], &odata);
}

int Ec600sAT_CIMI(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&imsiCmd[0], &odata);
}

int Ec600sAT_QCCID(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&qccidCmd[0], &odata);
}

int Ec600sATI(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&atiCmd[0], &odata);
}

int Ec600sAT_GMR(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&gmrCmd[0], &odata);
}

int Ec600sAT_QENG(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&qengCmd[0], &odata);
}

int Ec600sAT_QCFG_nwscanmode(int scanmode, char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtFmtCmdOne(&qcfgCmd[0], &odata, ATCMD_LEN, "nwscanmode",scanmode);
}

int Ec600sAT_COPS(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&copsCmd[0], &odata);
}

int Ec600sAT_CSQ(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&csqCmd[0], &odata);
}

int Ec600sAT_CCLK(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&cclkCmd[0], &odata);
}

int Ec600sAT_CGPADDR(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&cgpaddrCmd[0], &odata);
}

int Ec600sAT_CGMR(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&cgmrCmd[0], &odata);
}

int Ec600sAT_CGCONTRDP(char *obuf)
{
    ST_AT_EXE_OUT_DATA odata={0};
    odata.extract_data=(unsigned char*)obuf;
    return Ec600sAtCmdOne(&cgcontrdpCmd[0], &odata);
}


